#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 字符串结构定义，包含指向数据的指针和字符串的长度
typedef struct {
    char* data; // 字符串数据
    int length; // 字符串长度
} String;

// 初始化字符串结构，返回一个新的字符串对象
String* initString() {
    String* s = (String*)malloc(sizeof(String));
    if (s == NULL) { // 检查内存分配是否成功
        return NULL;
    }
    s->data = NULL; // 初始化数据指针为 NULL
    s->length = 0; // 初始化长度为 0
    return s;
}

// 为字符串赋值，给定字符串指针和赋值的数据
void stringAssign(String* s, const char* data) {
    if (s == NULL) { // 确保字符串结构不为空
        return;
    }
    if (s->data) { // 如果之前有数据，则释放
        free(s->data);
    }
    if (data == NULL) { // 如果传入的数据为空
        s->data = NULL;
        s->length = 0;
        return; // 不再继续
    }

    int len = strlen(data); // 计算新数据的长度
    s->data = (char*)malloc(len + 1); // 为新数据分配内存
    if (s->data == NULL) { // 检查分配是否成功
        s->length = 0;
        return;
    }

    strcpy(s->data, data); // 复制数据到字符串结构中
    s->length = len; // 更新字符串长度
}

// 打印字符串，如果字符串为空则打印 NULL
void printString(const String* s) {
    if (s == NULL || s->data == NULL) { // 检查字符串和数据指针是否为空
        printf("NULL");
    } else {
        printf("%s", s->data); // 打印字符串
    }
    printf("\n"); // 换行
}

// 强制匹配函数，检查子字符串是否在主字符串中
void forceMatch(const String* master, const String* sub) {
    // 确保字符串结构和数据不为空
    if (master == NULL || sub == NULL || master->data == NULL || sub->data == NULL) {
        printf("错误: 无效的字符串指针或 NULL 数据。\n");
        return;
    }

    if (sub->length == 0) { // 如果子字符串为空
        printf("强制匹配成功。\n");
        return; // 空字符串是任意字符串的子串
    }

    int i = 0, j = 0;
    int matchIndex = -1; // 记录最近一次匹配的位置

    // 遍历主字符串，寻找子字符串
    while (i < master->length) {
        if (master->data[i] == sub->data[j]) { // 如果字符匹配
            if (j == 0) { // 如果是子字符串的第一个字符
                matchIndex = i; // 更新匹配位置
            }
            j++; // 移动到子字符串的下一个字符
            if (j == sub->length) { // 如果匹配到子字符串的末尾
                printf("强制匹配成功。\n");
                return; // 匹配成功
            }
            i++; // 继续检查主字符串的下一个字符
        } else { // 如果字符不匹配
            if (j > 0) { // 如果已经有部分匹配
                i = matchIndex + 1; // 从上次匹配的位置继续
                j = 0; // 重置子字符串的索引
            } else {
                i++; // 向前移动主字符串的索引
            }
        }
    }

    printf("强制匹配失败。\n"); // 如果没有匹配成功
}

// 主函数，检查参数并执行字符串操作
int main(int argc, char* argv[]) {
    if (argc < 3) { // 检查命令行参数是否足够
        printf("错误: 需要两个参数来进行匹配。\n");
        return -1;
    }

    // 初始化两个字符串结构
    String* s = initString();
    String* s1 = initString();

    if (s == NULL || s1 == NULL) { // 确保初始化成功
        printf("错误: 初始化字符串失败。\n");
        return -1;
    }

    // 为两个字符串赋值
    stringAssign(s, argv[1]);
    stringAssign(s1, argv[2]);

    // 打印字符串
    printf("主字符串: ");
    printString(s);
    printf("子字符串: ");
    printString(s1);

    // 执行强制匹配
    forceMatch(s, s1);

    // 释放内存，防止内存泄漏
    free(s->data);
    free(s1->data);
    free(s);
    free(s1);

    return 0;
}
